`
https://leetcode.cn/problems/minimum-time-to-repair-cars/
`

/**
 * @param {number[]} ranks
 * @param {number} cars
 * @return {number}
 */
var repairCars = function (ranks, cars) {
  // t 时刻能否修好 cars 辆车
  const check = (t) => {
    let sum = 0
    for (const rank of ranks) {
      // 修好 s 辆车需要 t = ranks[i] * s ** 2 
      // t 时刻可以修好 s = Math.sqrt(t / ranks[i]) 辆车
      sum += Math.floor(Math.sqrt(t / rank))
      if (sum >= cars) return true
    }
    return false
  }

  // 找到两个循环不变量作为边界
  const minR = Math.min(...ranks)
  // 修得最快的还没修好一辆汽车
  let left = minR - 1
  // 修得最快的自己修好了所有汽车
  let right = minR * (cars ** 2)
  while (left + 1 < right) {
    const mid = left + Math.floor((right - left) / 2)
    if (check(mid)) {
      right = mid
    } else {
      left = mid
    }
  }
  return right
};